package com.jxdinfo.hussar.example.common.schedulingtask;

import com.jxdinfo.hussar.example.common.schedulingtask.dao.MdItemMapper;
import com.jxdinfo.hussar.example.common.schedulingtask.model.CBOItemMasterInventoryInfo;
import com.jxdinfo.hussar.example.common.schedulingtask.model.MdItem;
import com.jxdinfo.hussar.example.common.schedulingtask.service.MdItemService;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @Author QiaoBin
 * @Date 2024/4/02 15:49
 * @Description  md_item物料产品表的定时任务
 */
@Component
@AllArgsConstructor
public class MdItemScheduleTask {
    private static final Logger logger = LoggerFactory.getLogger(MdItemScheduleTask.class);

    private MdItemService mdItemService;
    private MdItemMapper mdItemMapper;

    /**
     * @Author QiaoBin
     * @Date 2024/04/07 18:06
     * @Description 物料表的定时任务-md_item
     */
//    @Scheduled(cron = "*/15 * * * * ?")
    @Scheduled(cron = "0 30 1 * * ?")  //凌晨一点30执行
    public void mdItemTask() {
        logger.info("\n用友-物料产品表-定时任务-开始执行");
        LocalDateTime nowTime = LocalDateTime.now();
        synchronized ("mdItemTask"){
            logger.info("用友-物料产品表-开始查询物料产品表中最大的同步时间");
            LocalDateTime scheduleDate = mdItemMapper.selectMaxScheduleDate();
            String scheduleDateString = "";
            if (scheduleDate != null) {
                scheduleDateString = scheduleDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
            //查询创建时间大于定时任务时间，查询出来后把所有数据全部插进去
            logger.info("\n用友-物料产品表-开始查询CBO_ItemMaster表中创建时间大于任务时间的数据,查询参数scheduleDateString={}", scheduleDateString);
            List<CBOItemMasterInventoryInfo> cboItemMasterInventoryInfoList = mdItemMapper.selectMoreSchedule(scheduleDateString);
            logger.info("\n用友-物料产品表-结束查询CBO_ItemMaster表中创建时间大于任务时间的数据,查询结果cboItemMasterInventoryInfoList={}，size={}", cboItemMasterInventoryInfoList,cboItemMasterInventoryInfoList.size());
            if (cboItemMasterInventoryInfoList.size() > 0) {
                ArrayList<MdItem> mdItemList = new ArrayList<>();
                for (int i = 0; i < cboItemMasterInventoryInfoList.size(); i++) {
                    logger.info("\n用友-物料产品表-当前循环次数i={}", i);
                    CBOItemMasterInventoryInfo cboItemMasterInventoryInfo = cboItemMasterInventoryInfoList.get(i);
                    MdItem mdItem = new MdItem();
                    mdItem.setItemId(cboItemMasterInventoryInfo.getMasterId());
                    mdItem.setItemCode(cboItemMasterInventoryInfo.getItemCode());  // 料号－》产品物料编码
                    mdItem.setItemName(cboItemMasterInventoryInfo.getItemName());            // 品名-》产品物料名称
                    mdItem.setSpecification(cboItemMasterInventoryInfo.getSpecification()); // 规格-》规格型号
                    mdItem.setEnableFlag(cboItemMasterInventoryInfo.getEnableFlag());  // 是否生效
                    mdItem.setItemTypeId(cboItemMasterInventoryInfo.getItemTypeId());  // 物料id
                    mdItem.setItemTypeCode(cboItemMasterInventoryInfo.getItemTypeCode());  // 物料id
                    mdItem.setItemTypeName(cboItemMasterInventoryInfo.getItemTypeName());  // 物料id
                    mdItem.setUnitOfMeasure(cboItemMasterInventoryInfo.getUnitOfMeasure());  // 单位
                    mdItem.setMeasureId(cboItemMasterInventoryInfo.getMeasureId());  // 单位Id
                    mdItem.setItemOrProduct("PRODUCT");
                    mdItem.setScheduleTime(nowTime);
                    mdItem.setStandardGrade(cboItemMasterInventoryInfo.getStandardGrade());
                    mdItem.setStartGrade(cboItemMasterInventoryInfo.getStartGrade());
                    mdItem.setEndGrade(cboItemMasterInventoryInfo.getEndGrade());
                    mdItem.setCreateBy(cboItemMasterInventoryInfo.getMasterCreatedBy());
                    mdItem.setCreateTime(cboItemMasterInventoryInfo.getMasterCreatedOn());
                    mdItem.setUpdateBy(cboItemMasterInventoryInfo.getMasterModifiedBy());
                    mdItem.setUpdateTime(cboItemMasterInventoryInfo.getMasterModifiedOn());
                    mdItem.setErpItemId(cboItemMasterInventoryInfo.getMasterId());
                    logger.info("\n用友-物料产品表-开始向list中存入数据，数据mdItem={},i={}", mdItem,i);
                    mdItemList.add(mdItem);
                }
                logger.info("\n用友-物料产品表-开始向md_item表中插入数据，数据mdItemList={}", mdItemList);
                boolean b = mdItemService.saveBatch(mdItemList, 100);
                logger.info("\n用友-物料产品表-结束向md_item表中插入数据，插入结果b={}", b);
            }
            if (scheduleDate == null) {
                logger.info("\n用友-物料产品表-查询不到任务时间，说明一次也没有同步，之间原封不动的插入就行,也就不需要后续更新");
                return;
            }
            if (scheduleDate != null) {
                //查询CBO_ItemMaster和子表CBO_InventoryInfo中更新时间大于定时任务时间，查询出来后把所有数据全部更新进去
                logger.info("\n用友-物料产品表-开始查询CBO_ItemMaster表中更新时间大于任务时间，查询参数scheduleDateString={}", scheduleDateString);
                List<CBOItemMasterInventoryInfo> masterAndInfoUpdateMoreScheduleList = mdItemMapper.selectUpdateMoreSchedule(scheduleDateString);
                logger.info("\n用友-物料产品表-结束查询CBO_ItemMaster表中更新时间大于任务时间,查询结果masterAndInfoUpdateMoreScheduleList={},数量size={}", masterAndInfoUpdateMoreScheduleList, masterAndInfoUpdateMoreScheduleList.size());

                if (masterAndInfoUpdateMoreScheduleList == null || masterAndInfoUpdateMoreScheduleList.size() == 0) {
                    logger.info("\n用友-物料产品表-没有查询到更新时间大于任务时间的CBO_ItemMaster和子表CBO_InventoryInfo数据");
                    return;
                }
                // moMoUpdateMoreScheduleList转成map集合
                logger.info("\n用友-物料产品表-开始把用友表中更新时间大于任务时间的数据转换成主键、对象的map集合");
                Map<Long, CBOItemMasterInventoryInfo> moMoUpdateMap = masterAndInfoUpdateMoreScheduleList.stream().collect(Collectors.toMap(CBOItemMasterInventoryInfo::getMasterId, t -> t));
                // 获取CBO_ItemMaster和子表CBO_InventoryInfo更新过的主键
                logger.info("\n用友-物料产品表-开始获取用友表中更新时间大于任务时间的数据的主键");
                List<Long> masterIdList = masterAndInfoUpdateMoreScheduleList.stream().map(CBOItemMasterInventoryInfo::getMasterId).collect(Collectors.toList());
                logger.info("\n用友-物料产品表-CBO_ItemMaster和子表CBO_InventoryInfo更新时间大于任务时间的主键集合masterIdList={},size={}", masterIdList, masterIdList.size());
                // 根据momo的主键去order和orderline表中查询数据momo_id=主键的记录，重新设置值并更新进去
                logger.info("\n用友-物料产品表-开始查询md_item中master_id=CBO_ItemMaster表中主键的数据,参数masterIdList={}", masterIdList);
                List<MdItem> tMaterialAchieveUpdateList = mdItemMapper.selectUpdateMoreScheduleOrder(masterIdList);
                logger.info("\n用友-物料产品表-结束查询md_item中master_id=CBO_ItemMaster表中主键的数据,结果tMaterialAchieveUpdateList={},size={}", tMaterialAchieveUpdateList, tMaterialAchieveUpdateList.size());
                if (tMaterialAchieveUpdateList.size() > 0) {
                    ArrayList<MdItem> updateAchieveList = new ArrayList<>();
                    for (int i = 0; i < tMaterialAchieveUpdateList.size(); i++) {
                        logger.info("\n用友-物料产品表-当前更新时间大于任务时间，md_item表更新，次数i={}", i);
                        MdItem mdItem = tMaterialAchieveUpdateList.get(i);
                        Long currentMasterId = mdItem.getErpItemId();
                        CBOItemMasterInventoryInfo cboItemMasterInventoryInfo = moMoUpdateMap.get(currentMasterId);
                        mdItem.setItemCode(cboItemMasterInventoryInfo.getItemCode());              // 料号－》产品物料编码
                        mdItem.setItemName(cboItemMasterInventoryInfo.getItemName());              // 品名-》物料名称
                        mdItem.setSpecification(cboItemMasterInventoryInfo.getSpecification());    // 规格-》规格型号
                        mdItem.setItemTypeId(cboItemMasterInventoryInfo.getItemTypeId());  // 物料id
                        mdItem.setItemTypeCode(cboItemMasterInventoryInfo.getItemTypeCode());  // 物料code
                        mdItem.setItemTypeName(cboItemMasterInventoryInfo.getItemTypeName());  // 物料name
                        mdItem.setEnableFlag(cboItemMasterInventoryInfo.getEnableFlag());          // 启用状态
                        mdItem.setUnitOfMeasure(cboItemMasterInventoryInfo.getUnitOfMeasure());    //单位
                        mdItem.setMeasureId(cboItemMasterInventoryInfo.getMeasureId());         //单位id
                        mdItem.setItemOrProduct("PRODUCT");
                        mdItem.setScheduleTime(nowTime);
                        mdItem.setStandardGrade(cboItemMasterInventoryInfo.getStandardGrade());
                        mdItem.setStartGrade(cboItemMasterInventoryInfo.getStartGrade());
                        mdItem.setEndGrade(cboItemMasterInventoryInfo.getEndGrade());
                        mdItem.setCreateBy(cboItemMasterInventoryInfo.getMasterCreatedBy());
                        mdItem.setCreateTime(cboItemMasterInventoryInfo.getMasterCreatedOn());
                        mdItem.setUpdateBy(cboItemMasterInventoryInfo.getMasterModifiedBy());
                        mdItem.setUpdateTime(cboItemMasterInventoryInfo.getMasterModifiedOn());
                        logger.info("\n用友-物料产品表-向updateAchieveList中存储待要更新的物料产品表信息,mdItem={}", mdItem);
                        updateAchieveList.add(mdItem);
                    }
                    logger.info("\n用友-物料产品表-开始更新md_item数据,列表updateAchieveList={}", updateAchieveList);
                    boolean u = mdItemService.updateBatchById(updateAchieveList);
                    logger.info("\n用友-物料产品表-结束更md_item数据,更新结果u={}", u);
                }
            }
        }
        logger.info("\n用友-物料产品表-定时任务-结束执行");
    }
}
